#include "destructibletile.h"

void explode(DELAY_PARAMS &params)
{
    // Get map
    CMap *pMap(CMapContainer::getInstance()->getCurrentMap());

    int *npTextureFrameIndex(
        reinterpret_cast<int*>(params.at(0).vpValue));
    CDestructibleTile *pTile(
        reinterpret_cast<CDestructibleTile*>(params.at(1).vpValue));

    // Get the height, width, depth of this tile
    int nHeight(pTile->getHeight());
    int nWidth(pTile->getWidth());
    int nDepth(pTile->getDepth());

    if ((*npTextureFrameIndex)++ == 3)
    {
        pTile->stopRepeat();

        // Create a new free tile.
        CTile *pNewTile(new CFreeTile(nHeight, nWidth, nDepth));

        // Set the tile at the height, width and depth in the map to
        // the newly created free tile.
        pMap->setTile(pTile->getHeight(), pTile->getWidth(), 
                      pTile->getDepth(), pNewTile);


        *npTextureFrameIndex = 0;

        //delete npTextureFrameIndex;
        npTextureFrameIndex = nullptr;
    }
    else
    {
        if ((*npTextureFrameIndex) == 1)
        {
            if (nHeight > 0)
                pMap->getTile(nHeight-1, nWidth, nDepth)->getDisplayable()->setSubsetDrawable(TILE_FACE_TOP);
            if (nHeight < pMap->getHeight() - 1)
                pMap->getTile(nHeight+1, nWidth, nDepth)->getDisplayable()->setSubsetDrawable(TILE_FACE_BOTTOM);

            if (nWidth > 0)
                pMap->getTile(nHeight, nWidth-1, nDepth)->getDisplayable()->setSubsetDrawable(TILE_FACE_RIGHT);
            if (nWidth < pMap->getWidth() - 1)
                pMap->getTile(nHeight, nWidth+1, nDepth)->getDisplayable()->setSubsetDrawable(TILE_FACE_LEFT);

            if (nDepth > 0)
                pMap->getTile(nHeight, nWidth, nDepth-1)->getDisplayable()->setSubsetDrawable(TILE_FACE_BACK);
            if (nDepth < pMap->getDepth() - 1)
                pMap->getTile(nHeight, nWidth, nDepth+1)->getDisplayable()->setSubsetDrawable(TILE_FACE_FRONT);

        }
        // Change texture
        stringstream sstream;
        sstream << "textures/tiles/explosions/box"
                << *npTextureFrameIndex
                << ".png";
        CTexture *pTexture(
            CTextureContainer::getInstance()->getTexture(sstream.str()));
        if (pTexture == nullptr)
        {
            pTexture = CTextureContainer::getInstance()->addTexture(sstream.str(),
                                        sstream.str(), 
                                        CDeviceManager::getInstance()->getDevice());
        }
        pTile->getDisplayable()->setTexture(pTexture, 0);
        pTile->getDisplayable()->setTexture(pTexture, 1);
        pTile->getDisplayable()->setTexture(pTexture, 2);
        pTile->getDisplayable()->setTexture(pTexture, 3);
        pTile->getDisplayable()->setTexture(pTexture, 4);
        pTile->getDisplayable()->setTexture(pTexture, 5);
        
    }
}

void CDestructibleTile::stopRepeat()
{
    myRepeat.stop();
}

CDestructibleTile::CDestructibleTile(const entid &nTileID, 
    const string &szTextureName, short int nHeight, short int nWidth, 
    short int nDepth) :
    CTile(nTileID, szTextureName, nHeight, nWidth, nDepth),
    myRepeat(100.0f, &explode, 4)
{
    setDestructible(true);
}



CDestructibleTile::CDestructibleTile(short int nHeight, 
                             short int nWidth, 
                             short int nDepth) 
    : CTile(ENT_TILE_DESTRUCTIBLE, "textures/tiles/box.png",
                        nHeight, nWidth, nDepth),
      myRepeat(100.0f, &explode, 4)
{
    setDestructible(true);
}

void CDestructibleTile::destroy()
{
    if (! myRepeat.isRunning() && !isBeingDestroyed())
    {
        setDestroyed();

        // Allow us to walk into the squares
        setWalkable(true);

        // Get map
        CMap *pMap(CMapContainer::getInstance()->getCurrentMap());

        myRepeat.registerParam(new int(0), utils::TYPE_SLONG, sizeof(int));
        myRepeat.registerParam(this, utils::TYPE_OTHER, sizeof(*this));

        // Get the height, width, depth of this tile
        int nHeight(getHeight());
        int nWidth(getWidth());
        int nDepth(getDepth());

        // Create reference to current tile
        CTile *pCurrentTile (pMap->getTile(nHeight, nWidth, nDepth));

        // Create and start the repeat
        myRepeat.start();

        if (getPickup() != nullptr)
        {
            getPickup()->show();
        }
    }
}

void CDestructibleTile::tick()
{
    myRepeat.tick();
}